package cn.itsource.system.aop;

import cn.itsource.system.domain.Log;
import cn.itsource.system.jwt.JwtUtil;
import cn.itsource.system.jwt.Payload;
import cn.itsource.system.mapper.LogMapper;
import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.Signature;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.reflect.MethodSignature;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.time.LocalDateTime;
import java.util.Arrays;
import java.util.Enumeration;

/**
 * @Author: Neuronet
 * @Date: 2023-08-28
 * @Description: 操作日志记录切面类
 * @Version:1.0
 */
@Aspect
@Component
public class LogsAspect {

    @Autowired
    private HttpServletRequest request;

    @Autowired(required = false)
    private LogMapper logMapper;

    // 指定annotation切点表达式，查找@Log注解
    @Around("@annotation(cn.itsource.annotation.Log)")
    public void around(ProceedingJoinPoint pjp) throws Throwable {
        Log log = new Log();
        // 1、获取操作人id 通过登录获取
        String token = request.getHeader("token");
        Payload payload = JwtUtil.parseJwtToken(token);
            Long operId = payload.getLogininfo().getId();

            log.setOperId(operId);

            // 2.开始操作时间
            LocalDateTime operTime = LocalDateTime.now();
            log.setOperTime(operTime);
            // 3.设置操作类名
            String className = pjp.getTarget().getClass().getName();
            log.setClassName(className);
            // 4.操作方法名
            String methodName = pjp.getSignature().getName();
            log.setMethodName(methodName);
//         4.方法参数
//        Object[] args = pjp.getArgs();
//        String methodParams = Arrays.toString(args);
            // 5.执行目标方法以及获取到方法返回值
            long beginTime = System.currentTimeMillis();
            Object result = pjp.proceed();
            long endTime = System.currentTimeMillis();

            // 6.操作耗时
//        Long operTime = endTime - beginTime;
            //返回值 @TODO
            Signature signature = pjp.getSignature();
            if (signature instanceof MethodSignature) {
                MethodSignature methodSignature = (MethodSignature) signature;
                // 实例化
                String returnType = methodSignature.getReturnType().getName();
                log.setReturnValue(returnType);
            }

            // 7.操作Ip
            String ip = request.getRemoteAddr();
            log.setIp(ip);

//        // 8.记录操作日志，因为没有做登录，所以操作Id和操作用户名称写死

//        Log log = new Log(null, operId,  operTime, className, methodName,  returnType,ip);
//
            logMapper.add(log);
    }
}